// YaP IRC - Main Form.
//Copyright (C) 2006  Pierre-Alain DAVID

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.

//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//#if DEBUG
//#define VERBOSE__
//#endif

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using IrcNetLib;
using IrcNetLib.Core;
using IrcNetLib.Core.DCC;
using IrcNetLib.Core.Ping;
using YaP.Library;
using YaP.Library.Extensions;
using YaP.Library.IrcParser;
using YaP.Library.mircLib;
using YaP.Library.XmlModels;
using YaP.Library.YapControls;
using YaP.Properties;
using ConnectionState = YaP.Library.ConnectionState;
using EventJoinArgs = YaP.Library.IrcParser.EventJoinArgs;
using EventKickArgs = YaP.Library.IrcParser.EventKickArgs;
using EventModeArgs = YaP.Library.IrcParser.EventModeArgs;
using EventNickArgs = YaP.Library.IrcParser.EventNickArgs;
using EventPartArgs = YaP.Library.IrcParser.EventPartArgs;
using EventPingArgs = YaP.Library.IrcParser.EventPingArgs;
using EventQuitArgs = YaP.Library.IrcParser.EventQuitArgs;

namespace YaP.Forms
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    /// 
    public partial class MainForm
    {
        #region Delegates

        public delegate void SyncBehaviour(bool state);

        public delegate void SyncCloseChild(int destination);

        public delegate void SyncCreateChan(string chn);

        public delegate void SyncCreatePvChan(string nom);

        public delegate void SyncDelegate(string todisp);

        public delegate void SyncListDelegate(string destination, string msg);

        /// <summary>
        ///	Les events
        /// </summary>
        /// 
        public delegate void SyncPutOnChan(ChanForm win, string @from, string toput);

        public delegate void SyncRichDelegate(int destination, string from, string msg, Type montype);

        public delegate void SyncStatusText(string msg);

        public delegate void ThreadWroteMd5Handler(object sender, EventArgs e);

        #endregion

        private const string Crlf = "\r\n";
        public const string Version = "0.5.2 Beta";
        private ManualResetEvent _allDone;
        public string Altnick;

        public bool Autorejoin;
        private WeakReference _chanListWr;
        public bool ChannelListDisp;
        public string Currfile;
        public string CurrMd5;
        private readonly System.Windows.Forms.ToolStripItem _emptyone;
        public System.IO.FileStream Fstream;
        public int I;
        private readonly Library.AliasesFactory _myAliaseFactory;
        public byte[] Mybuff;
        public string Nickname;
        private SideBarRenderer _sbr;
        private bool _nickInUsePending;
        private ConnectionState _cnState;
        public bool Writable;
        public PingEngine PingEngine;
#if VERBOSE__
        public DebugForm dbg;
#endif
#if DEBUG
#endif

        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //

            _mainThreadId = Thread.CurrentThread.ManagedThreadId;

            InitializeComponent();
            _sbr = new SideBarRenderer();
            sideBarStrip.Renderer = _sbr;

            toolStrip1.Renderer = _sbr;
            MenuRenderer mbr = new MenuRenderer();
            I = -1;
            Writable = true;
            CurrMd5 = null;
            Currfile = null;
            _childArray = new List<ChildDescriptor>();
            _nbenfants = 0;
            // TabAction = new string[16];
            Autorejoin = true;
            _emptyone = sideBarStrip.Items[1];
            var optFact = new YaP.Library.OptionsFactory();
            Nickname = optFact.CurrentConfig.NICK;
            Altnick = optFact.CurrentConfig.ALT;
            _hostname = optFact.CurrentConfig.PREVSERV;
            int.TryParse(optFact.CurrentConfig.PREVPORT, out _port);
            // TabLogs = new ArrayList();
            _myAliaseFactory = new YaP.Library.AliasesFactory();

            _dataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            GetAliasFileFromXml();
        }

        /// <summary>
        /// Le tableau des enfants
        /// </summary>
        internal StatusForm MyStatus
        {
            get
            {
                var x = from c in _childArray where c.Type == "Status" select c;
                if (!x.Any())
                    return null;
                ChildDescriptor stat = x.First();
                return (StatusForm)stat.Window;
            }
        }

        [STAThread]
        public static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }

        private void GetAliasFileFromXml()
        {
            if (File.Exists(_dataFolder + @"\aliaslist.xml"))
            {
                XmlSerializer xmls = new XmlSerializer(typeof(List<AliasFileDesc>));
                XmlTextReader reader = new XmlTextReader(_dataFolder + @"\aliaslist.xml");
                try
                {
                    AliasFileCollection = xmls.Deserialize(reader) as List<AliasFileDesc>;
                }
                catch (FileNotFoundException)
                {
                    AliasFileCollection = new List<AliasFileDesc>();
                    reader.Close();
                    WriteAliasFileToXml();
                    //this.GetAliasFileFromXML();
                }
                catch (InvalidOperationException)
                {
                    AliasFileCollection = new List<AliasFileDesc>();
                    reader.Close();
                    WriteAliasFileToXml();
                    //this.GetAliasFileFromXML();
                }
            }
            else
            {
                AliasFileCollection = new List<AliasFileDesc>();
                WriteAliasFileToXml();
                // this.GetAliasFileFromXML();
            }
        }

        private void WriteAliasFileToXml()
        {
            XmlSerializer xmls = new XmlSerializer(typeof(List<AliasFileDesc>));
            XmlTextWriter writer = new XmlTextWriter(_dataFolder + @"\aliaslist.xml", Encoding.UTF8);
            xmls.Serialize(writer, AliasFileCollection);
        }

        private void EraseServerList()
        {
            serverListToolStripMenuItem.DropDownItems.Clear();
        }

        /// <summary>
        /// Create Server List in main menu
        /// </summary>
        /// <param name="xmlFile">XML server file</param>
        private void PopulateServersList(string xmlFile)
        {
            EraseServerList();
            Library.ServerFactory servFact = new YaP.Library.ServerFactory();
            foreach (YaP.Library.NetworkServerList itm in servFact.WorkingList.Items)
            {
                ToolStripMenuItem newCat = new ToolStripMenuItem();
                newCat.Text = itm.NetworkName;
                foreach (YaP.Library.ServerItem srv in itm.ServerList)
                {
                    ToolStripServerLabel toadd = new ToolStripServerLabel(srv.ServerHost, srv.ServerPort.ToString(),
                                                                          itm.NetworkName);
                    toadd.Click += toadd_Click;
                    newCat.DropDownItems.Add(toadd);
                }
                serverListToolStripMenuItem.DropDownItems.Add(newCat);
            }
        }

        private void ServFact_OnUpdated(ServerFactory sender)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Raised when a Server item is clicked in main menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toadd_Click(object sender, EventArgs e)
        {
            ToolStripServerLabel clicked = (ToolStripServerLabel)sender;
            _hostname = clicked.addField;
            int.TryParse(clicked.portField, out _port);
            Createsocket(_hostname, _port);
            _myIrcClient.Connect();
        }

        public static string InputBox(string prompt, string title, string defaultValue)
        {
            InputBoxForm ib = new InputBoxForm();
            ib.FormPrompt = prompt;
            ib.FormCaption = title;
            ib.DefaultValue = defaultValue;
            ib.ShowDialog();
            string s = ib.InputResponse;
            ib.Close();
            return s;
        }

        private void Createsocket(string hn, int po)
        {
            _myIrcClient = new IrcClient(hn, po);
            _myIrcClient.ClientUnableConnect += MyIrcClientClientUnableConnect;
            _myIrcClient.ClientConnected += MyIrcClient_onConnected;
           // _myIrcClient.ClientConnecting += MyIrcClient_onConnecting;
            _myIrcClient.OnReceived += MyIrcClient_onReceived;
            _myIrcClient.DataSend += MyIrcClientDataSend;
            _myIrcClient.ClientConnecting += MyIrcClientConnecting;
            _myIrcClient.ClientDisconnected += MyIrcClientClientDisconnected;
            OnWroteMd5 += Action_onWroteMD5;
        }

        private void MyIrcClientClientDisconnected(object sender, SocketsArgs e)
        {
            _myIrcClient = null;
            MakeBehaviourConnected(false);
            MyStatus.WriteLine("-" + Crlf + "*** Disconnected" + Crlf);
            PingEngine?.Stop();
            PingEngine = null;
        }

        private void MyIrcClientConnecting(object sender, SocketsArgs e)
        {
            MyStatus.WriteLine("-" + Crlf + " *** Attempting to connect to " + _hostname + Crlf);
        }

        private void MyIrcClientDataSend(object sender, EventSendArgs e)
        {
#if VERBOSE__
            dbg.Write2Debug(e.Message);
#endif
            switch (e.Command)
            {
                case "PRIVMSG":
                    if (e.Message != "VERSION")
                        PutOnChan(e.Destination, Nickname, e.Message);
                    else
                        MyStatus.WriteLine("*** CTCP VERSION SENT");
                    //MyStatus.Disp("*** CTCP VERSION SENT");
                    break;
                //case "JOIN":
                //    this.createChannel(e.Message);
                //    break;
            }
        }

        private void MyIrcClientClientUnableConnect(object sender, SocketsArgs e)
        {
            //throw new Exception("The method or operation is not implemented.");
            MyStatus.WriteLine("*** Error connecting : " + (sender));
            //MyStatus.Disp(((ircsockets.IrcClient)sender).ToString());
        }

        private void Disconnect()
        {
            List<ChildDescriptor> tokill = GetAllChannel();
            foreach (ChildDescriptor ch in tokill)
            {
                KillChild(ch.Window);
            }

            _myIrcClient.Disconnect();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="from"></param>
        public void Treatline(string msg, string from)
        {
            while (msg.StartsWith(" "))
            {
                msg = msg.TrimStart(" ".ToCharArray());
            }

            if (msg.StartsWith("/"))
            {
                string[] cutted = msg.Split(" ".ToCharArray());
                cutted[0] = cutted[0].Substring(1);
                cutted[0] = cutted[0].ToUpper();
                string[] args;
                if (cutted.Length >= 2)
                {
                    switch (cutted[0])
                    {
                        case "FREEZE":
                            break;
                        case "BACKCOLOR":
                            string strcolor = cutted[1].ToLower();
                            Color cc = Color.White;
                            switch (strcolor)
                            {
                                case "black":
                                    cc = Color.Black;
                                    break;
                                case "white":
                                    cc = Color.White;
                                    break;
                            }
                            ((ChanForm)GetChannel(from).Window).ChangeRichBackColor(cc);
                            break;
                        case "RAW":
                            args = new string[1];
                            for (int i = 1; i < cutted.Length; i++)
                                args[0] = args[0] + " " + cutted[i];

                            args[0] += Crlf;
                            DoCmd(cutted[0], args);
                            break;
                        case "TOPIC":
                        case "ME":
                            args = new string[2];
                            args[0] = from;
                            for (int i = 1; i < cutted.Length; i++)
                                args[1] = args[1] + " " + cutted[i];
                            DoCmd(cutted[0], args);
                            break;
                        case "KICK":
                            args = new string[3];
                            args[0] = from;
                            args[1] = cutted[1];
                            for (int i = 2; i < cutted.Length; i++)
                                args[2] = args[2] + " " + cutted[i];
                            DoCmd(cutted[0], args);
                            break;
                        default:
                            args = new string[cutted.Length - 1];
                            for (int k = 1; k < cutted.Length; k++)
                            {
                                args[k - 1] = cutted[k];
                            }
                            DoCmd(cutted[0], args);
                            break;
                    }
                }
                else if (cutted.Length == 1)
                {
                    args = new string[1];
                    args[0] = from;
                    DoCmd(cutted[0], args);
                }
            }
            else if (from != "\tStatus")
                SendMessageToServer(msg, from);
            else
                MyStatus.WriteLine("Cannot Send Message In Status");
        }

        public void SendMessageToServer(string tosend, string destination)
        {
            _myIrcClient.SendIrcCmd("PRIVMSG", destination, tosend);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tosend"></param>
        /// <param name="destination"></param>
        public void SendNoticeToServer(string tosend, string destination)
        {
            _myIrcClient.SendIrcCmd("NOTICE", destination, tosend);
        }

        public string GetYaPVersion()
        {
            return Version;
        }
     
        /// <summary>
        /// Execute a service command
        /// </summary>
        /// <param name="cmd">Command Name</param>
        /// <param name="args"></param>
        /// <returns></returns>
        public async Task DoCmd(string cmd, string[] args)
        {
            string rfcMessage = string.Empty;
            AliasDesc description = new AliasDesc();
            if ((cmd == "NICK") && (_cnState == ConnectionState.Connecting))
            {
                _myIrcClient.SendIrcCmd(cmd, string.Empty, args.Merge(" "));
                Nickname = args[0];
            }
            if (_myAliaseFactory.IsAlias(cmd, out description))
            {
                if (description.Type == AliasType.RFC2812)
                {
                    rfcMessage = _myAliaseFactory.AliasToRFC(cmd, args);
                    _myIrcClient.SendRawString(rfcMessage);
                }
                else if (description.Type == AliasType.Internal)
                {
                    switch (cmd)
                    {
                        case "CHARSET":
                            _myIrcClient.GlobalCharset = args[0];
                            break;
                        case "SERVER":
                            Disableconnect();
                            if (_myIrcClient != null)
                                Disconnect();

                            if (args.Length >= 2)
                            {
                                try
                                {
                                    _hostname = args[0];
                                    _port = int.Parse(args[1]);
                                    Createsocket(_hostname, _port);
                                    await _myIrcClient.Connect(args.Length >= 2 ? args[2] : "");
                                }
                                catch (FormatException)
                                {
                                    MyStatus.WriteLine("-" + Crlf + "Server command: Bad port" + Crlf);
                                }
                            }
                            else
                            {
                                MyStatus.WriteLine("-" + Crlf + "Server command: missing port argument" + Crlf);
                            }
                            break;
                    }
                }
            }
            else if (_myIrcClient != null)
                _myIrcClient.SendIrcCmd(cmd, string.Empty, args.Merge(" "));


        }

        private void GetChanList()
        {
            if (_myIrcClient != null)
                _myIrcClient.SendIrcCmd("LIST", "", "");
        }

        public void LogIt(string @from, string dest, string msg, string type, string window)
        {

        }

        public async Task CreatePvChan(string nom)
        {

            CreatePvChan_sync(nom);
        }

        private void CreatePvChan_sync(string nom)
        {
            PrivateForm win = new PrivateForm(nom, MdiChildren.Length, new ChannelStyle(), this);
            PrivateChildArguments args = new PrivateChildArguments(nom);
            win.MdiParent = this;

            win.Show();
            sideBarStrip.Items.Remove(_emptyone);
            ChildDescriptor pv = new ChildDescriptor(win, sideBarStrip.Items.Add(nom), "Private", args);
            pv.Button.Click += GeneralStripButtonClick;
            pv.Button.TextAlign = ContentAlignment.MiddleLeft;
            pv.Button.ImageAlign = ContentAlignment.MiddleLeft;
            pv.Button.Image = Properties.Resources.user_go;
            pv.Button.AutoSize = false;
            pv.Button.Width = 97;
            pv.Button.Height = 28;
            _childArray.Add(pv);
            pv.Button.Text = nom;
            sideBarStrip.Items.Add(_emptyone);
            _allDone.Set();
        }

        public string[] GetUserChannels(string nick)
        {
            string[] toreturn = new string[MdiChildren.Length];
            int k = 0;
            for (int i = 1; i < MdiChildren.Length; i++)
            {
                if (MdiChildren[i].GetType() == typeof(ChanForm))
                {
                    if (((ChanForm)MdiChildren[i]).IsOn(nick))
                    {
                        toreturn[k] = ((ChanForm)MdiChildren[i]).nom;
                        k += 1;
                    }
                }
            }
            return toreturn;
        }

        /// <summary>
        /// Display an action on the specified channel. if destination == "ALL"
        /// The specified action si shown on every channel.
        /// </summary>
        /// <param name="type">Action Type</param>
        /// <param name="from">From who ?</param>
        /// <param name="dest">To ?</param>
        /// 
        private void close_child(int toclose)
        {
            (MdiChildren[toclose]).Close();
        }

        public void actiononchan(string type, string from, string dest)
        {
            ChildDescriptor chn = GetChannel(dest);
            if (chn != null)
                ((ChanForm)chn.Window).addevent(type, from, "");
        }

        public void actiononchan(string type, string from, string dest, string msg)
        {
            ChildDescriptor chn = GetChannel(dest);
            if (chn != null)
                ((ChanForm)chn.Window).addevent(type, from, msg);
        }

        public async Task ChangeStatusText(string text)
        {

            MdiChildren[0].Text = "Status - " + _hostname + " [" + text + "]";

        }

        private void chgstatustext_sync(string text)
        {
            MdiChildren[0].Text = "Status - " + _hostname + " [" + text + "]";
        }

        public void Chgmode(string from, string dest, string msg)
        {
            while (msg.StartsWith(" "))
                msg = msg.TrimStart(" ".ToCharArray());
            if (dest.StartsWith("#"))
            {
                string flag = msg[0].ToString();
                string[] tomod = msg.Split(" ".ToCharArray());
                string[] operations = new string[tomod[0].Length];

                for (int k = 1; k < tomod[0].Length; k++)
                    operations[k - 1] = tomod[0][k].ToString();
                ChildDescriptor chn = GetChannel(dest);
                switch (flag)
                {
                    case "+":
                        for (int k = 0; k < operations.Length; k++)
                        {
                            if (operations[k] == "o")
                                ((ChanForm)chn.Window).opuser(tomod[1]);
                            if (operations[k] == "v")
                                ((ChanForm)chn.Window).voiceuser(tomod[1]);
                            if (operations[k] == "h")
                                ((ChanForm)chn.Window).halfopuser(tomod[1]);
                        }
                        break;
                    case "-":
                        for (int k = 0; k < operations.Length; k++)
                        {
                            if (operations[k] == "o")
                                ((ChanForm)chn.Window).deopuser(tomod[1]);
                            if (operations[k] == "v")
                                ((ChanForm)chn.Window).devoice(tomod[1]);
                            if (operations[k] == "h")
                                ((ChanForm)chn.Window).dehalfop(tomod[1]);
                        }
                        break;
                }
            }
        }



        private async void MyIrcClient_onReceived(object sender, SocketsArgs e)
        {
            #region on_received

#if VERBOSE__
            dbg.Write2Debug(e.myreceivedtext);
#endif
            string lusocks = e.myreceivedtext;
            try
            {
                while (lusocks.EndsWith("\0"))
                    lusocks = lusocks.TrimEnd("\0".ToCharArray());

                IRCParser monparser = new IRCParser();
                monparser.OnDCC += monparser_OnDCC;
                monparser.OnJoin += monparser_OnJoin;
                monparser.OnKick += monparser_OnKick;
                monparser.OnMode += monparser_OnMode;
                monparser.OnMsg += monparser_OnMsg;
                monparser.OnNick += monparser_OnNick;
                monparser.OnNotice += monparser_OnNotice;
                monparser.OnNumeric += monparser_OnNumeric;
                monparser.OnPart += monparser_OnPart;
                monparser.OnQuit += monparser_OnQuit;
                monparser.OnPing += monparser_OnPing;
                monparser.OnWelcome += monparser_OnWelcome;
                monparser.OnMotd += monparser_OnMotd;
                monparser.OnListStart += monparser_OnListStart;
                monparser.OnList += monparser_OnList;
                monparser.OnListEnd += monparser_OnListEnd;
                monparser.OnNames += monparser_OnNames;
                monparser.OnBanList += monparser_OnBanList;
                monparser.OnTopic += monparser_OnTopic;
                monparser.OnUnknownCommand += monparser_OnUnknownCommand;
                monparser.OnNick += monparser_OnNick;
                monparser.OnNoticeAuth += monparser_OnNoticeAuth;
                monparser.OnNickInUse += monparser_OnNickInUse;
                monparser.OnCtcp += new IRCParser.EventCtcpHandler(monparser_OnCtcp);
                monparser.OnBadChannelKey += new IRCParser.EventIrcErrReply(monparser_OnBadChannelKey);
                monparser.OnChannelIsFull += new IRCParser.EventIrcErrReply(monparser_OnChannelIsFull);
                monparser.OnChanOpPrivNeeded += new IRCParser.EventIrcErrReply(monparser_OnChanOpPrivNeeded);
                monparser.OnInviteOnlyChan += new IRCParser.EventIrcErrReply(monparser_OnInviteOnlyChan);
                monparser.OnKeyAlreadySet += new IRCParser.EventIrcErrReply(monparser_OnKeyAlreadySet);
                monparser.OnReplyWhoisUser += new IRCParser.EventRplWhoisUserHandler(monparser_OnReplyWhoisUser);
                monparser.GlobalError += monparser_GlobalError;
                monparser.Parse(lusocks);



            #endregion
            }
            catch (NullReferenceException)
            {
            }
        }

        void monparser_GlobalError(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine(string.Format("{0} : {1}", message.type.ToString("D"), message.Message));
        }

        void monparser_OnReplyWhoisUser(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine("Whois Reply: " + message.Message);
        }

        void monparser_OnKeyAlreadySet(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine("Key is already set for " + message.Message);
        }

        void monparser_OnInviteOnlyChan(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine("Can't join " + message.Message + " because it is invite only.");
        }

        void monparser_OnChanOpPrivNeeded(object sender, IrcFormatedMessage message)
        {
            ChildDescriptor chd = GetChannel(message.Origin);
            (chd.Window as ChanForm).addevent(string.Empty, string.Empty, "You're not a channel operator");

        }

        void monparser_OnChannelIsFull(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine("Channel is full: " + message.Message);
        }

        void monparser_OnBadChannelKey(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine("Bad channel key:" + message.Message);


        }

        void monparser_OnCtcp(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine(string.Format("[4CTCP FROM{0}] :{1}", message.Origin, message.Message));
        }

        void monparser_OnNickInUse(object sender, IrcFormatedMessage message)
        {
            this._nickInUsePending = true;
            MyStatus.WriteLine(message.Message);
            //MyStatus.Disp(Message.msg);
        }

        void monparser_OnNoticeAuth(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine(message.Message);
        }

        private void monparser_OnUnknownCommand(object sender, string command)
        {
            MyStatus.WriteLine("Warning Unknown Command: " + command);
        }

        private void monparser_OnTopic(object sender, EventTopicArgs e)
        {
            ChildDescriptor chn = GetChannel(e.ChannelName);
            ((ChanForm)chn.Window).changetopic(e.Topic);
        }

        private void monparser_OnBanList(object sender, IrcFormatedMessage message)
        {
            ChildDescriptor chn = GetChannel(message.Origin);
            if (((ChanForm)chn.Window).ClearBanListNextTime)
            {
                ((ChanForm)chn.Window).ClearBanList();
                ((ChanForm)chn.Window).ClearBanListNextTime = false;
            }
            ((ChanForm)chn.Window).AddToBanList(message.Message);
        }

        private void monparser_OnNames(object sender, IrcFormatedMessage message)
        {
            Fullist(message.Destination, message.Message);
        }

        private void monparser_OnListEnd(object sender, IrcFormatedMessage message)
        {
            _chanList.InUse = false;
            MyStatus.WriteLine("End of channels list.");
        }

        private async void monparser_OnList(object sender, IrcFormatedMessage message)
        {


            await OnListPoolCallBack(message);
        }

        private void monparser_OnListStart(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine("Getting channels list ...");
            CreateListChannelForm();

            _chanList.InUse = true;
        }

        private void monparser_OnMotd(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine(message.Message + Crlf);
        }

        private void monparser_OnWelcome(object sender, IrcFormatedMessage message)
        {
            MyStatus.WriteLine(message.Message + Crlf);
            _cnState = ConnectionState.Connected;
        }

        private void monparser_OnPing(object sender, EventPingArgs e)
        {
            _myIrcClient.SendIrcCmd("PONG", "", e.Origin);
            MyStatus.WriteLine("-" + Crlf + "*** PING ? PONG!" + Crlf);
        }

        private void monparser_OnQuit(object sender, EventQuitArgs e)
        {
            //throw new NotImplementedException();
            string origin = GetNickFromMask(e.Nick);

            string[] tocheck = GetUserChannels(origin);
            int n = 0;
            while (tocheck[n] != null)
            {
                Deluser(tocheck[n], origin);
                actiononchan("QUIT", origin, tocheck[n], e.Reason);
                n += 1;
            }
        }

        private void monparser_OnPart(object sender, EventPartArgs e)
        {
            //throw new NotImplementedException();
            string nick = GetNickFromMask(e.Nick);
            Deluser(e.Chan, nick);
            actiononchan("PART", nick, e.Chan);
        }

        private void monparser_OnNumeric(object sender, EventNumericArgs e)
        {
            IrcFormatedMessage monmsg = new IrcFormatedMessage();
            ChildDescriptor chn;
        }

        private void ShowDccBox()
        {
            DccPopUpForm dccFrm = new DccPopUpForm();
            ManualResetEvent waiter = new ManualResetEvent(false);
            dccFrm.StartPosition = FormStartPosition.Manual;

            dccFrm.Top = -150;
            dccFrm.Left = 50;
            dccFrm.Show();
            for (int i = 0; i < 20; i++)
            {
                dccFrm.Top += i;
                waiter.WaitOne(10, false);
            }
        }

        private void GoDccBox(object dccfrm)
        {
            DccPopUpForm dccFrm = (DccPopUpForm)dccfrm;
            ManualResetEvent waiter = new ManualResetEvent(false);
            dccFrm.StartPosition = FormStartPosition.Manual;

            dccFrm.Top = -150;
            dccFrm.Left = 50;
            dccFrm.Show();
            for (int i = 0; i < 20; i++)
            {
                dccFrm.Top += i;
                waiter.WaitOne(10, false);
            }
        }

        private void monparser_OnNotice(object sender, Library.IrcParser.IrcFormatedMessage message)
        {
            //throw new NotImplementedException();
            if (message.Origin != null) MyStatus.WriteLine("[4NOTICE FROM" + message.Origin + "] :" + message.Message);
        }

        private void monparser_OnNick(object sender, EventNickArgs e)
        {
            // throw new NotImplementedException();
            string nick = GetNickFromMask(e.OldNick);

            if (nick == Nickname)
            {
                ChangeStatusText(e.NewNick);
                Nickname = e.NewNick;
            }
            string[] tocheck = GetUserChannels(nick);
            int n = 0;
            while (tocheck[n] != null)
            {
                Chguser(tocheck[n], nick, e.NewNick);
                actiononchan("NICK", nick, tocheck[n], e.NewNick);

                n += 1;
            }
        }

        private void monparser_OnMsg(object sender, IrcFormatedMessage message)
        {
            if (message.Message.StartsWith("VERSION "))
            {
                SendNoticeToServer(
                    "VERSION YaP! v" + GetYaPVersion() + " .NET (" + System.Environment.Version.Major +
                    System.Environment.Version.MajorRevision + System.Environment.Version.Minor +
                    System.Environment.Version.MinorRevision + ") ", GetNickFromMask(message.Origin));
                MyStatus.WriteLine("-" + Crlf + "*** CTCP VERSION RECEIVED FROM " + GetNickFromMask(message.Origin) + Crlf);
            }
            else
            {
                if (message.Destination == Nickname)
                    PutOnPrivate(GetNickFromMask(message.Origin), message.Message);
                else
                    PutOnChan(message.Destination, GetNickFromMask(message.Origin), message.Message);
            }
        }

        private void monparser_OnMode(object sender, EventModeArgs e)
        {
            string nick = GetNickFromMask(e.Destination);

            Chgmode(e.Origin, nick, e.Modes);

            if (nick != Nickname)
                actiononchan("MODE", e.Origin, nick, e.Modes);
        }

        private void monparser_OnKick(object sender, EventKickArgs e)
        {
            Deluser(e.Chan, e.Nick);
            if (e.Nick == Nickname)
                actiononchan("KICKEDME", GetNickFromMask(e.Origin), e.Chan, e.Reason);
            else
                actiononchan("KICK", GetNickFromMask(e.Origin), e.Nick, e.Chan + "\t" + e.Reason);
        }

        private void monparser_OnJoin(object sender, EventJoinArgs e)
        {
            string nickName = GetNickFromMask(e.Nick);

            if (nickName == Nickname)
            {

                CreateChannel(e.Chan);
            }
            else
            {
                Newcomer(e.Chan, nickName);
                actiononchan("JOIN", nickName, e.Chan);
            }
        }

        private void monparser_OnDCC(object sender, EventDCCArgs e)
        {
            //ShowDccBox();
            DialogResult dr = MessageBox.Show(GetNickFromMask(e.Origin) + " sends you" + e.FileName, "DCC Send",
                                              MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);

            if (dr != DialogResult.OK) return;
            Thread tw = new Thread(DccWork);
            tw.IsBackground = true;
            tw.Start(e);

            BeginInvoke((MethodInvoker)delegate
                                            {
                                                toolStripProgressBar1.Value = 0;


                                            });


            BeginInvoke((MethodInvoker)delegate
                                            {
                                                toolStripProgressBar1.Visible = true;
                                                dccToolTip.SetToolTip(statusStrip1, "Accept ?");
                                                dccToolTip.Show("Accept ?", this,
                                                                new Point(System.Convert.ToInt32(Size.Width / 2),
                                                                          System.Convert.ToInt32(Size.Height / 2)), 60000);
                                            });
        }

        private void DccWork(object args)
        {
            EventDCCArgs e = (EventDCCArgs)args;
            DccClient dcc = new DccClient(e.FileName, e.Address, e.Port, e.Size);
            dcc.OnStartReceive += Dcc_OnStartReceive;
            dcc.OnError += Dcc_OnError;
            dcc.OnFileExists += Dcc_OnFileExists;
            dcc.OnProgress += Dcc_OnProgress;
            dcc.OnFinished += Dcc_OnFinished;
            dcc.StartReceive();
        }

        private void Dcc_OnFinished(object sender, EventArgs e)
        {
            Invoke((MethodInvoker)delegate
                                       {
                                           Label tag = new Label();
                                           tag.Text = "finished!";
                                           statusStrip1.Items.Add("finished");
                                           toolStripProgressBar1.Visible = false;
                                       });
        }

        private void Dcc_OnProgress(object sender, EventProgressArgs e)
        {
            Invoke((MethodInvoker)delegate
                                       {
                                           toolStripProgressBar1.Value =
                                               Convert.ToInt32(e.Percent * toolStripProgressBar1.Maximum / 100);
                                           toolStripProgressBar1.ToolTipText = e.BytePerSec + "KB/sec";
                                       });
        }

        private void Dcc_OnFileExists(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void Dcc_OnError(object sender, EventArgs e)
        {
            MyStatus.WriteLine("*** Error on connecting to DCC host");
        }

        private void Dcc_OnStartReceive(object sender, EventArgs e)
        {
            toolStripProgressBar1.ToolTipText = "On Progress";
        }

        private async Task OnListPoolCallBack(object context)
        {
            IrcFormatedMessage message = (IrcFormatedMessage)context;
            await FullListChan(message);
        }

        private  Task FullListChan(object objectArgs)
        {
            IrcFormatedMessage args = (IrcFormatedMessage)objectArgs;
             _chanList.AddChan(args.Destination, args.Origin, args.Message);
            return Task.CompletedTask;
        }

        private void CreateListChannelForm()
        {
            if (!(ChannelListDisp))
            {
                Invoke((MethodInvoker)delegate
                                           {
                                               sideBarStrip.Items.Remove(_emptyone);
                                               Forms.GriddedChannelList toadd = new YaP.Forms.GriddedChannelList();
                                               //ChanListForm toadd = new ChanListForm();
                                               ChildDescriptor list = new ChildDescriptor(toadd,
                                                                                          sideBarStrip.Items.Add("List"),
                                                                                          "CList", null);
                                               _childArray.Add(list);
                                               list.Button.Text = "Channel list";
                                               list.Button.Image = mesimages.Images[8];
                                               list.Button.TextAlign = ContentAlignment.MiddleLeft;
                                               list.Button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
                                               list.Button.Size = new Size(102, 26);
                                               list.Button.ImageAlign = ContentAlignment.TopLeft;
                                               list.Button.ImageTransparentColor = Color.White;
                                               list.Button.ImageScaling = ToolStripItemImageScaling.None;
                                               list.Button.Click += GeneralStripButtonClick;
                                               toadd.MdiParent = this;
                                               toadd.Show();
                                               ChannelListDisp = true;
                                               _chanList = toadd;
                                               sideBarStrip.Items.Add(_emptyone);
                                           });
            }
        }

        /// <summary>
        /// Get nickname from a raw IRC Line
        /// </summary>
        /// <param name="mask"></param>
        /// <returns></returns>
        public static string GetNickFromMask(string mask)
        {
            if (mask.Contains('!'))
            {
                int exPos = mask.IndexOf('!');
                return mask.Substring(1, exPos - 1);
            }
            return mask;
        }

        private ChildDescriptor GetChannelList()
        {
            var x = from c in _childArray where (c.Type == "CList") select c;
            if (x.Count() > 0)
                return x.First();
            else
                return null;
        }

        private ChildDescriptor GetPrivate(Form win)
        {
            var x = from c in _childArray where (c.Type == "Private" && c.Window == win) select c;
            if (x.Count() > 0)
                return x.First();
            else
                return null;
        }

        private ChildDescriptor GetPrivate(string name)
        {
            var x = from c in _childArray
                    where (c.Type == "Private" && ((PrivateChildArguments)c.Arguments).Name == name)
                    select c;
            if (x.Count() > 0)
                return x.First();
            else
                return null;
        }

        private ChildDescriptor GetChild(Form win)
        {
            var x = from c in _childArray where (c.Type != "Status" && c.Window == win) select c;
            if (x.Count() > 0)
                return x.First();
            else
                return null;
        }

        private List<ChildDescriptor> GetAllChild()
        {
            var x = from c in _childArray where c.Type != "Status" select c;
            List<ChildDescriptor> returnList = new List<ChildDescriptor>();
            foreach (ChildDescriptor ch in x)
            {
                returnList.Add(ch);
            }

            return returnList;
        }

        private List<ChildDescriptor> GetAllChannel()
        {
            var x = from c in _childArray where c.Type == "Channel" select c;
            List<ChildDescriptor> returnList = new List<ChildDescriptor>();
            foreach (ChildDescriptor ch in x)
            {
                returnList.Add(ch);
            }

            return returnList;
        }

        private ChildDescriptor GetChannel(ToolStripItem butt)
        {
            var x = from c in _childArray where c.Button == butt select c;
            return x.First();
        }

        private ChildDescriptor GetChannel(Form win)
        {
            var x = from c in _childArray where c.Window == win select c;
            return x.First();
        }

        private ChildDescriptor GetChannel(string name)
        {
            name = name.ToLower();
            var x = from c in _childArray
                    where (c.Type == "Channel" && ((ChannelChildArguments)c.Arguments).Name == name)
                    select c;
            if (x.Count() > 0)
                return x.First();
            else
            {
                Monitor.Enter(this);
                Monitor.Wait(this, 250);
                Monitor.Exit(this);
                x = from c in _childArray
                    where (c.Type == "Channel" && ((ChannelChildArguments)c.Arguments).Name == name)
                    select c;
                if (x.Count() > 0)
                    return x.First();
                else
                {
                    return null;
                }
            }
        }

        private void Deluser(string channel, string nick)
        {
            try
            {
                if (!(nick == Nickname))
                    ((ChanForm)GetChannel(channel).Window).removeuser(nick);
            }
            catch (IndexOutOfRangeException ex)
            {
#if VERBOSE__
                dbg.Write2Debug(ex.ToString());
#endif
            }
        }

        private void Chguser(string channel, string old, string newnick)
        {
            ((ChanForm)GetChannel(channel).Window).chguser(old, newnick);
        }

        private void Newcomer(string channel, string nick)
        {
            IrcUser toadd = new IrcUser(nick);
            ((ChanForm)GetChannel(channel).Window).adduser(toadd);
        }

        private void PutOnPrivate(string @from, string msg)
        {
            ChildDescriptor pv = GetPrivate(@from);
            if (pv != null)
            {
                pv.Window.Invoke((MethodInvoker)(() => ((PrivateForm)pv.Window).addmsg(@from, msg)));
            }
            else
            {
                CreatePvChan(@from);
                PutOnPrivate(@from, msg);
            }
        }

        private void PutOnChan(string destination, string from, string toput)
        {
            ChildDescriptor chn = GetChannel(destination);
            if (chn == null)
                return;

            PutOnChan_sync((ChanForm)chn.Window, from, toput);

        }


        private void PutOnChan_sync(ChanForm win, string @from, string toput)
        {
            win.AddMessage(@from, toput);

        }


        private void Fullist(string destination, string lesnoms)
        {
            ChildDescriptor chn = GetChannel(destination);

            //AsyncDispListArgs mesargs = new AsyncDispListArgs(k, lesnoms);
            fullist_sync(destination, lesnoms);

        }

        private void fullist_sync(string destination, string msg)
        {
            ChildDescriptor chn = GetChannel(destination);

            string[] towrite = msg.Split((char)32);
            IrcUser[] maliste = new IrcUser[towrite.Length];
            for (int k = 0; k < towrite.Length; k++)
                maliste[k] = new IrcUser(towrite[k]);


            ((ChanForm)chn.Window).putlist(maliste);
        }

        public void KillPrivate(Form win)
        {
            ChildDescriptor tokill = GetPrivate(win);
            if (tokill == null) return;
            sideBarStrip.Items.Remove(tokill.Button);
            _childArray.Remove(tokill);
        }

        public void KillChild(Form win)
        {
            ChildDescriptor tokill = GetChild(win);
            if (tokill == null) return;
            sideBarStrip.Items.Remove(tokill.Button);
            _childArray.Remove(tokill);
        }

#if MS_NET
        [DllImport("Kernel32.dll")]
        public static extern bool SetProcessWorkingSetSize(IntPtr pHandle, int minimumWorkingSetSize,
                                                           int maximumWorkingSetSize);
#endif

        public void KillChannelList(Form win)
        {
            ChildDescriptor tokill = GetChannelList();
            if (tokill == null) return;
            sideBarStrip.Items.Remove(tokill.Button);
            _childArray.Remove(tokill);
#if DEBUG
            _chanListWr = new WeakReference(_chanList);
            _chanListWr.Target = _chanList;
#endif
            _chanList.Dispose();
            _chanList = null;
            ChannelListDisp = false;
#if MS_NET
            SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
#endif
        }

        public void KillChannel(Form win)
        {
            ChildDescriptor tokill = GetChannel(win);
            if (tokill != null)
            {
                sideBarStrip.Items.Remove(tokill.Button);
                _childArray.Remove(tokill);
            }
        }

        private void CreateStatus()
        {
            ChildDescriptor status = new ChildDescriptor(new StatusForm(this), sideBarStrip.Items[0], "Status", null);
            status.Window.MdiParent = this;
            _childArray.Add(status);
            status.Window.Show();
        }

        /// <summary>
        /// Add a channel form to the main form
        /// </summary>
        /// <param name="nomchannel"></param>
        private void CreateChannel(string nomchannel)
        {
            string lenom = nomchannel;

            lenom = lenom.TrimEnd((char)13);
            lenom = lenom.TrimEnd((char)10);
            sideBarStrip.Items.Remove(_emptyone);
            //New way to manage mdi children - 2007
            ChanForm win = new ChanForm(this, nomchannel, MdiChildren.Length, new ChannelStyle());
            win.MdiParent = this;
            ChildDescriptor chn = new ChildDescriptor(win, sideBarStrip.Items.Add(lenom), "Channel",
                                                      new ChannelChildArguments(lenom));
            _childArray.Add(chn);
            chn.Button.TextAlign = ContentAlignment.MiddleLeft;
            chn.Button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
            chn.Button.Size = new System.Drawing.Size(102, 26);
            chn.Button.ImageAlign = ContentAlignment.TopLeft;
            chn.Button.Image = Resources.application_view_detail;
            chn.Button.ImageTransparentColor = Color.White;
            chn.Button.ImageScaling = ToolStripItemImageScaling.None;
            chn.Button.Click += GeneralStripButtonClick;
            chn.Window.Show();
            sideBarStrip.Items.Add(_emptyone);
            //---------------------------------------


            _nbenfants += 1;
            XmlTextReader checker = null;
            try
            {
                checker = new XmlTextReader(lenom + ".log.xml");
            }
            catch (FileNotFoundException)
            {
            }
            if (checker != null)
            {
                //_checker.Close();
                //XmlTextWriter _tw = new XmlTextWriter(lenom + ".log.xml", null);
                //_tw.delete
            }
        }


        private void Action_onWroteMD5(object sender, EventArgs e)
        {
            if (CurrMd5 != null) MyStatus.WriteLine(CurrMd5);
        }

        public void FlushSigNewMsg(string @from)
        {
            int i = 0;
            while (sideBarStrip.Items[i].Text != @from)
                i += 1;
            sideBarStrip.Items[i].ForeColor = Color.Black;
        }

        public void SigNewMsg(string @from)
        {
            ChildDescriptor chn = GetChannel(@from);
            if (ActiveMdiChild != chn.Window)
            {
                chn.Button.ForeColor = Color.Red;
            }
        }

        private void Disableconnect()
        {
            menuStrip1.Items[2].Enabled = false;
        }


        public void ClickSwitch(ChildDescriptor myChild)
        {
            foreach (ToolStripItem ts in sideBarStrip.Items)
            {
                if (ts.GetType() == (typeof(ToolStripButton)))
                    (ts as ToolStripButton).Checked = false;
            }
            (myChild.Button as ToolStripButton).Checked = true;
        }

        public void Getfocus(System.Windows.Forms.ToolStripButton tofocus)
        {
            var x = from c in _childArray where c.Button == tofocus select c;
            ChildDescriptor mychild = x.First();
            ClickSwitch(mychild);
            ActivateMdiChild(mychild.Window);
            mychild.Window.Focus();
        }

        public event ThreadWroteMd5Handler OnWroteMd5;

        private void MainFormLoad(object sender, System.EventArgs e)
        {
#if VERBOSE__
            dbg = new DebugForm();
            dbg.Show();
            System.Timers.Timer MyTimer = new System.Timers.Timer(6000);
            MyTimer.Start();
            MyTimer.Elapsed += new System.Timers.ElapsedEventHandler(MyTimer_Elapsed);



#endif

            CreateStatus();
            PopulateServersList("ServersList.xml");
            //StreamForm stForm = new StreamForm(new Uri("http://www.dailymotion.com/video/xqdgta_webtv-nanashor_videogames"));
            //stForm.Show();
        }

#if VERBOSE__
        void MyTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (ChanListWr != null)
            {
                dbg.Write2Debug("ChanList Mem state: " + ChanListWr.IsAlive.ToString() + crlf);
                dbg.Write2Debug("ChanList String: " + (ChanListWr.Target as Forms.GriddedChannelList).ToString() + crlf);
            }
        }
#endif

        private void ConnectToolStripMenuItemClick(object sender, System.EventArgs e)
        {
            Createsocket(_hostname, _port);
            _myIrcClient.Connect();
        }


        private void ConnectToPreviousServerToolStripMenuItemClick(object sender, System.EventArgs e)
        {
            Createsocket(_hostname, _port);
            _myIrcClient.Connect();
        }

        private void MyIrcClient_onConnected(object sender, ConnectedArgs e)
        {
            if (!string.IsNullOrWhiteSpace(e.ServerPassword))
            {
                _myIrcClient.SendIrcCmd("PASS", "", e.ServerPassword);
            }
            //this.MyIrcClient.SendIrcCmd("PASS", "", "");
            this._cnState = ConnectionState.Connecting;
            _myIrcClient.SendIrcCmd("NICK", "", " " + Nickname);
            _myIrcClient.SendIrcCmd("USER", "",
                                   "localname " + _myIrcClient.GetLocalAdress() + " " + _myIrcClient.Hostname +
                                   " :YaP! IRC ");
            //this.MyIrcClient.sendcmd("MODE", "", "tafiouzdotnet -w");
            _myIrcClient.ReceiveText();
            ChangeStatusText(Nickname);
            MakeBehaviourConnected(true);
            CONFIG currConfig = new CONFIG();
            Library.OptionsFactory optf = new OptionsFactory();
            currConfig = optf.CurrentConfig;
            currConfig.PREVPORT = _myIrcClient.Port.ToString();
            currConfig.PREVSERV = _myIrcClient.Hostname;
            optf.CurrentConfig = currConfig;
            this.PingEngine = new PingEngine(_myIrcClient.Hostname,_myIrcClient.Port,10000);
            PingEngine.PingDone += PingEngine_PingDone;
            PingEngine.Start();
        }

        private void PingEngine_PingDone(object sender, PingEngineArgs args)
        {
            this.tsItemPing.Text = args.RoundTripTime + "Ms";
        }

        private async Task MakeBehaviourConnected(bool state)
        {

            MakeBehaviourConnected_sync(state);
        }

        private void MakeBehaviourConnected_sync(bool state)
        {
            if (state)
            {
                statusStrip1.Items[1].Text = "ClientConnected";
                statusStrip1.Items[1].Image = mesimages.Images[1];
                _emptyone.Enabled = true;
                disconnectToolStripMenuItem.Enabled = true;
                connectToolStripMenuItem.Enabled = false;
                tsConnectDisconnectButton.Image = Properties.Resources.lightning_delete;
                tsConnectDisconnectButton.ToolTipText = "Disconnect";
                tsConnectDisconnectButton.Click -= ConnectToolStripMenuItemClick;
                tsConnectDisconnectButton.Click += disconnectToolStripMenuItem_Click;
            }
            else
            {
                statusStrip1.Items[1].Text = "Not ClientConnected";
                statusStrip1.Items[1].Image = mesimages.Images[0];
                _emptyone.Enabled = false;
                disconnectToolStripMenuItem.Enabled = false;
                connectToolStripMenuItem.Enabled = true;
                tsConnectDisconnectButton.Image = Properties.Resources.lightning;
                tsConnectDisconnectButton.Click -= disconnectToolStripMenuItem_Click;
                tsConnectDisconnectButton.Click += ConnectToolStripMenuItemClick;
            }
        }

        private void Action_onJoin(object sender, EventArgs e)
        {
        }


        private void GeneralStripButtonClick(object sender, System.EventArgs e)
        {
            var clicked = (System.Windows.Forms.ToolStripButton)sender;
            Getfocus(clicked);
        }

        private void ToolStripButton1Click(object sender, System.EventArgs e)
        {
            Getfocus((System.Windows.Forms.ToolStripButton)sender);
            MdiChildren[0].Focus();
        }

        private void ToolbarToolStripMenuItemClick(object sender, System.EventArgs e)
        {
            if (toolbarToolStripMenuItem.Checked)
            {
                toolStrip1.Visible = false;
                toolbarToolStripMenuItem.Checked = false;
            }
            else
            {
                toolStrip1.Visible = true;
                toolbarToolStripMenuItem.Checked = true;
            }
        }


        private void SwitchbarToolStripMenuItemClick(object sender, System.EventArgs e)
        {
            if (switchbarToolStripMenuItem.Checked)
            {
                sideBarStrip.Visible = false;
                switchbarToolStripMenuItem.Checked = false;
            }
            else
            {
                sideBarStrip.Visible = true;
                switchbarToolStripMenuItem.Checked = true;
            }
        }

        private void OtherChannelToolStripMenuItemClick(object sender, System.EventArgs e)
        {
            _myIrcClient.SendIrcCmd("JOIN", "", InputBox("Which Channel ?", "YaP!", "#test"));
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (_myIrcClient.Connected)
                    _myIrcClient.SendIrcCmd("QUIT", "", "YaP!");
            }
            catch (NullReferenceException)
            {
            }
        }

        private void toolStrip1_Click(object sender, EventArgs e)
        {
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
        }

        private void tileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileVertical);
        }

        private void ascaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.Cascade);
        }

        private void MainForm_MdiChildActivate(object sender, EventArgs e)
        {
            ChildDescriptor chn = GetChild(ActiveMdiChild);
            if (chn != null)
            {
                chn.Button.ForeColor = Color.Black;
                Getfocus((ToolStripButton)chn.Button);
            }
        }

        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Disconnect();
        }

        private void aboutYaPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutForm about = new AboutForm(Version);
            about.Show();
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OptionsForm myopt = new OptionsForm();
            myopt.ShowDialog();
            PopulateServersList("ServersList.xml");
        }

        private void toolStripProgressBar1_DoubleClick(object sender, EventArgs e)
        {
            toolStripProgressBar1.Visible = false;
        }

        private void dccToolTip_Popup(object sender, PopupEventArgs e)
        {
        }

        private Process OpenFolder(string path)
        {
            try
            {
                return Process.Start(path);
            }
            catch (Exception)
            {
                MyStatus.WriteLine("Download folder not found ...");
                return null;
            }
        }

        private void toolStripButton4_Click_1(object sender, EventArgs e)
        {
            OpenFolder(_dataFolder + "\\Received\\");
        }

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            Visible = (!(Visible));
        }

        private void AliasesToolStripButton_Click(object sender, EventArgs e)
        {
            //this.MyAliaseFactory.SaveToXML("sysalias.xml");
            Forms.EditorForm edForm = new YaP.Forms.EditorForm(AliasFileCollection);
            edForm.OnMainBackColorChanged += new MainFormConfigurator.MainBackColorChanged(edForm_OnMainBackColorChanged);
            edForm.OnMainBackImageChanged += new MainFormConfigurator.BackImgChanged(edForm_OnMainBackImageChanged);
            edForm.OnMainImgModeChanged += new MainFormConfigurator.ImgModeChanged(edForm_OnMainImgModeChanged);
            edForm.ShowDialog();
            AliasFileCollection = edForm.FileList;
            WriteAliasFileToXml();
        }

        void edForm_OnMainImgModeChanged(object sender, ImageLayout layout)
        {
            this.BackgroundImageLayout = layout;
        }

        void edForm_OnMainBackImageChanged(object sender, string filePath)
        {
            Bitmap bmp = new Bitmap(filePath);
            this.BackgroundImage = bmp;
        }

        void edForm_OnMainBackColorChanged(object sender, Color c)
        {
            this.BackColor = c;
        }

        #region Private members

        private readonly string _dataFolder;
        private readonly int _mainThreadId;
        private List<AliasFileDesc> _aliasfilecollectionField;
        private Forms.GriddedChannelList _chanList;
        private List<ChildDescriptor> _childArray;
        private string _hostname;
        private IrcClient _myIrcClient;
        private int _nbenfants;
        private int _port;
        // private Dictionary<string, AliasDesc> AliasDictionary;

        private List<AliasFileDesc> AliasFileCollection
        {
            get { return _aliasfilecollectionField; }
            set
            {
                _aliasfilecollectionField = value;
                var activeScript = (from lst in value
                                    where lst.Active
                                    select lst).ToList();
                foreach (AliasFileDesc fd in activeScript)
                {
                    AliasParser ap = new AliasParser(fd.FilePath);
                    foreach (var v in ap.Dictionnary.ToList())
                    {
                        _myAliaseFactory.AddToDictionnary(v.Key, v.Value);
                    }
                }
            }
        }

        #endregion
        #region ToolStrip Displacement

        private bool _dragStarted;
        private void toolStrip2_MouseDown(object sender, MouseEventArgs e)
        {
            Rectangle myrect = new Rectangle(sideBarStrip.Location.X, sideBarStrip.Location.Y, sideBarStrip.Width, sideBarStrip.Height);
            Pen myPen = new Pen(Brushes.Black);
            myPen.Brush = Brushes.Black;
            myPen.DashStyle = new DashStyle();
            Graphics gfx = this.CreateGraphics();
            gfx.DrawRectangle(myPen, myrect);
            _dragStarted = true;

        }
        #endregion

        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            _dragStarted = false;
        }

        private void topToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sideBarStrip.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
            sideBarStrip.Dock = DockStyle.Top;
            sideBarStrip.Size = new Size(100, 90);
        }

        private void tsButtonChannels_Click(object sender, EventArgs e)
        {
           
        }

        private void toolStripStatusLabel4_Click(object sender, EventArgs e)
        {

        }
    }
}